<template>
<div 
    class="tetrisBuild"
    :style="{
        width: `${data.size * 10}px`,
        height: `${data.size * 20}px`,
    }" 
>

    <!-- 场地 -->
    <div class="item flex-[10%] flex items-center justify-center" v-for="(item, index) in data.tetrisList" :key="index" 
        :style="{
            height: `${data.size}px`,
            top: `-${data.size * 2}px`,
            backgroundColor: item.color || 'transparent',
        }" 
        :class="{
            notRight: item.x == 9,
            notBottom: item.y == 19,
            top: item.y < 0,
            hasColor: item.color,
        }"
        @click="handleClick(index)"
        @mousemove="handleMouseenter(index)"
    >
    </div>

    <canvas width="100%" height="100%" id="canvas"></canvas>

</div>

<div 
    class="mouse" 
    :style="{
        top: mouseY + 'px',
        left: mouseX + 'px',
    }"
    v-if="props.mode == 'pen' && !props.onlyCourt"
    :class="{hasBlock: props.penMode != 'block'}"
>
    <div v-if="props.penMode == 'block'" class="block" :style="{
        width: `${data.size / 2}px`,
        height: `${data.size / 2}px`,
        backgroundColor: buildColor,
    }">
    </div>

    <viewBlock
        v-else
        :minoType="props.penMode" 
        :size="data.size"
    />

</div>
</template>

<script lang="ts" setup>
import { ref, reactive, onActivated, defineExpose, defineProps } from "vue";
import { 
    useWindowSize,
    useWindowFocus,
    watchDebounced,
    useMousePressed,
    useMouse,
    useClipboard,
} from '@vueuse/core'
import mino from "@/data/mino.json"
import useAppStore from '@/pinia'
const app = useAppStore()

const { x: mouseX, y: mouseY } = useMouse({ touch: false })

const props = defineProps({
    mode: {
        type: String,
        default: 'pen',
    },
    penMode: {
        type: String,
        default: 'block',
    },
    onlyCourt: {
        type: Boolean,
        default: false,
    },
})

const { copy } = useClipboard()

const { pressed } = useMousePressed()

const data = reactive({
    size: 0,
    tetrisList: [],
    list: [],
})
let buildColor = ref('')
buildColor.value = mino.find(i => i.type == 'build').color


const { height: WindowHeight } = useWindowSize()
const windowResize = () => {
    initTetrisSize()
}
// 防抖监听WindowHeight变化
watchDebounced (WindowHeight, windowResize, { debounce: 200 })

const initTetrisSize = () => {
    const height = Math.floor(WindowHeight.value * 0.9)
    const size = Math.floor(height / 20)
    data.size = size
}

const initList = () => {
    let list = []
    for (let y = -2; y < 20; y++) {
        for (let x = 0; x < 10; x++) {
            list.push({
                x,
                y,
                color: '',
                type: ''
            })
        }
    }
    list = list.map((i, index) => {
        i.index = index
        return i
    })
    data.tetrisList = list
    data.list = []
}

const render = () => {
    let res = data.tetrisList.map(i => { // 重置
        i.color = ''
        return i
    })
    data.list.map(i => { // 绘制
        res[i.index].color = i.color
    })
    data.tetrisList = res
}

const handleClick = (index) => { // 画布点击
    if (props.onlyCourt) return
    let mode = props.mode
    if (mode == 'pen') {
        let hasIndex = data.list.findIndex(i => i.index == index)
        if (hasIndex != -1) {
            data.list = data.list.filter(i => i.index != index)
        } else {
            let item = data.tetrisList[index]
            if (item.y < 0) return
            data.list.push({
                index,
                color: buildColor.value,
                x: item.x,
                y: item.y,
            })
        }
        render()
    }
    else if (mode == 'clearLine') {
        let y = data.tetrisList[index].y
        data.list = data.list.filter(i => i.y != y)
        if (data.list && data.list.length) {
            data.list = data.list.map(i => {
                if (i.y < y) {
                    i.y++,
                    i.index = i.index + 10
                }
                return i
            })
        }
        render()
    }
}

const handleMouseenter = (index) => { // 画布鼠标长按滑动
    if (props.onlyCourt) return
    let mode = props.mode
    if (pressed.value && mode == 'pen') {
        let item = data.tetrisList[index]
        if (item.y < 0 || item.color) return
        data.list.push({
            index,
            color: buildColor.value,
            x: item.x,
            y: item.y,
        })
        render()
    }
}

// const initCanvas = () => {
//     const canvas = new fabric.Canvas('canvas', {
//         backgroundColor: 'transparent',
//     })
//     canvas.selection = true // 画布是否可选中。默认true；false 不可选中
//     canvas.selectionColor = 'rgba(106, 101, 216, 0.3)' // 画布鼠标框选时的背景色
//     canvas.selectionBorderColor = "#1d2786" // 画布鼠标框选时的边框颜色
//     canvas.selectionLineWidth = 6 // 画布鼠标框选时的边框厚度
// }

onActivated(() => {
    initTetrisSize()
    initList()
})

const clearCanvas = () => { // 清空
    data.list = []
    data.tetrisList.forEach(i => {
        i.color = ''
    })
}

const reversal = () => { // 反转
    let list = data.tetrisList.filter(i => i.y >= 0).map(i => {
        return {
            index: i.index,
            color: buildColor.value
        }
    })
    list = list.filter(i => !data.list.some(item => item.index == i.index))
    data.list = list
    render()
}

const exportList = () => {
    let list = data.list
    if (list.length == 0) return app.showTopMessage('请先放置方块！您要导出空气喵？', 'error')
    let res = { list: list.map(i => i.index) }
    // 导出文件
    let blob = new Blob([JSON.stringify(res)], { type: 'text/plain;charset=utf-8' });
    let url = URL.createObjectURL(blob);
    let link = document.createElement('a');
    link.href = url;
    link.download = 'build.json';
    link.click();
    URL.revokeObjectURL(url);
}

const exportListText = () => {
    let list = data.list
    if (list.length == 0) return app.showTopMessage('请先放置方块！您要导出空气喵？', 'error')
    let res = { list: list.map(i => i.index) } as any
    res = JSON.stringify(res)
    // 粘贴板
    const { copy } = useClipboard()
    copy(res)
    app.showTopMessage('已复制到粘贴板喵~', 'success')
}

const importListText = async () => {
    // 粘贴板
    let copyText = await navigator.clipboard.readText();
    if (copyText) {
        try {
            let res = JSON.parse(copyText)
            data.list = res.list.map(i => {
                return {
                    index: i,
                    color: buildColor.value
                }
            })
            render()
        } catch (error) {
            app.showTopMessage('粘贴板内容格式错误喵~', 'error')
        }
    }
}

defineExpose({
    clearCanvas,
    reversal,
    exportList,
    exportListText,
    importListText,
})

</script>

<style lang="scss" scoped>
// 变量
$border_b: rgba(255, 255, 255, 0.5);
$border: rgba(255, 255, 255, 0.1);
$bg: rgba(255, 255, 255, 0.2);
.mouse {
    position: fixed;
    left: 0;
    top: 0;
    pointer-events: none;
    opacity: 0.3;
    .block {
        border-radius: 10%;
    }
    &.hasBlock {
        transform: translate(-50%, -50%);
    }
}
.tetrisBuild {
    border: 1px solid $border_b;
    border-top: none;
    box-sizing: border-box;
    display: flex;
    flex-wrap: wrap;
    position: relative;
    perspective: 100vw;
    .item {
        border: 1px solid $border;
        border-left: none;
        border-top: none;
        position: relative;
        // 绕轴旋转
        transform-style: preserve-3d;
        transform: rotate3d(1,0,0, -10deg);
        &.notRight {
        border-right: none;
        }
        &.notBottom {
        border-bottom: none;
        }
        &.top {
        opacity: 0.8 !important;
        }
        &.hasColor {
            opacity: 1;
            border-radius: 16%;
            &:hover {
                opacity: 0.8;
            }
        }
        &.shadow {
        opacity: 0.2 !important;
        }
        &.targetItem {
        z-index: 9;
        position: absolute;
        }
        &.animate_grind {
        animation: grind 0.8s;
        }
    }
}
</style>